package com.zhouhailin.shirospringbootdemo.config;

import com.zhouhailin.shirospringbootdemo.shiro.realm.CustomerRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * Shiro配置类
 *
 * @Author zhouhailin
 * @date 2023/1/4 19:48
 */
@Configuration
public class ShiroConfig {

    /**
     * ShiroFilter过滤器创建【请求的过滤规则】
     * ShiroFilter过滤所有请求【拦截器。默认会拦截所有请求】
     *
     * 1、authc  ：所有url都必须认证通过才可以访问，authc代表shiro中的一个filter
     * 2、anon   ：所有url都可以匿名访问
     *
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        // 创建shiro的filter
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 注入安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String, String> map = new HashMap<String, String>();
        // 说明 index.jsp 需要认证之后才能展示
        map.put("/index.jsp", "authc");
//        map.put("/user/login", "anon");
//        map.put("/**", "authc");

        // 配置认证和授权规则
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);


//        // 公共资源一定是在受限资源上面，不然会造成死循环
//        Map<String, String> map = new HashMap<String, String>();
        // 表示为公共资源，一定是在受限资源上面
//        map.put("/user/login", "anon");
//        map.put("/user/register", "anon");
        // 表示受限资源需要认证和授权
//        map.put("/**", "authc");

        // 设置认证界面路径
//        shiroFilterFactoryBean.setLoginUrl("/login.jsp");
//        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

//    /**
//     * 安全管理器配置
//     * @Qualifier("customerRealm")
//     *
//     * @param realm
//     * @return
//     */
//    @Bean
//    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("customerRealm") Realm customerRealm) {
//        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//        defaultWebSecurityManager.setRealm(customerRealm);
//
//        return defaultWebSecurityManager;
//    }

    /**
     * 创建安全管理器
     *
     * @param realm
     * @return
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm) {
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        // 给安全管理设置Realm
        defaultWebSecurityManager.setRealm(realm);

        return defaultWebSecurityManager;
    }

    /**
     * 创建自定义Realm
     *
     * @return
     */
    @Bean
    public Realm getRealm() {
        CustomerRealm customerRealm = new CustomerRealm();

        // 1、修改凭证校验匹配器
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        // 2、设置加密算法为md5
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        // 3、设置散列次数
        hashedCredentialsMatcher.setHashIterations(1024);
        customerRealm.setCredentialsMatcher(hashedCredentialsMatcher);

        // 4、开启缓存管理
        customerRealm.setCachingEnabled(true);
        customerRealm.setAuthorizationCachingEnabled(true);
        customerRealm.setCacheManager(new EhCacheManager());

//        // 4、开启缓存管理
//        // 开启全局缓存
//        customerRealm.setCachingEnabled(true);
//        // 认证认证缓存
//        customerRealm.setAuthenticationCachingEnabled(true);
//        customerRealm.setAuthenticationCacheName("authenticationCache");
//        // 开启授权缓存
//        customerRealm.setAuthorizationCachingEnabled(true);
//        customerRealm.setAuthorizationCacheName("authorizationCache");

        return customerRealm;
    }
}
